﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace Microsoft.Samples.Kinect.BodyBasics.Controls
{
    /// <summary>
    /// TCPClient.xaml 的交互逻辑
    /// </summary>
    public partial class TCPClient : UserControl
    {
        //客户端
        private TcpClient tcpClient = null;
        //private IPAddress serverIP = null;
        private string ipAddress = "127.0.0.1";
        private int portNumber = 8080;

        //
        private NetworkStream stream;

        //发送数据缓冲区
        private Queue<Package> packagesSend = null;
        private byte[] receivedBuffer = new byte[2100];
        private  int sendLength = 50;

        private bool start_flag = false;

        //接收线程
        private Thread receiveThread;
        //是否需要一条发送线程？这样可能导致动作的延迟，也可以采取直接截断的方法
        private Thread sendThread;

        public int SendLength { get => sendLength; set => sendLength = value; }
        public bool IsTcpConnected
        {
            get
            {
                return tcpClient.Connected;
            }
        }

        public TcpClient TcpClient { get => tcpClient; set => tcpClient = value; }

        public delegate void DataReceivedHandle(byte[] bytes);
        public event DataReceivedHandle DataReceivedEvent;

        public TCPClient()
        {
            InitializeComponent();

            Init_tcpClient();
        }

        private void Init_tcpClient()
        {
            tcpClient = new TcpClient();
            packagesSend = new Queue<Package>(sendLength);
            
        }

        private void startListening()
        {
            while (start_flag)
            {
                if (stream.DataAvailable)
                {
                    if (DataReceivedEvent != null)
                    {
                        byte[] buffer = new byte[2100];
                        stream.Read(buffer, 0, buffer.Length);
                        Array.Copy(buffer, receivedBuffer, buffer.Length);
                        DataReceivedEvent(receivedBuffer);
                    }
                }

            }
        }

        //每隔一段时间发送给一次
        private void startSend()
        {
            while (start_flag)
            {
                if (packagesSend.Count > 0)
                {
                    byte[] sendBuffer = packagesSend.Dequeue().SendBuffer;
                    if (stream.CanWrite)
                    {
                        stream.Write(sendBuffer, 0, sendBuffer.Length);
                    }
                    Console.Write("sendBuffer:");
                    foreach(byte b in sendBuffer)
                    {
                        Console.Write(b.ToString("x"));
                    }
                    //stream.Flush();
                    packagesSend.Clear();
                    //防止发送数据量过大，对舵机造成损坏
                    Thread.Sleep(100);
                }
            }
        }

        private void btn_connect_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ipAddress = txb_ipAddress.Text;
                IPAddress iP = IPAddress.Parse(ipAddress);
                portNumber = int.Parse(txb_portNumber.Text);
                tcpClient.Connect(iP, portNumber);
                stream = tcpClient.GetStream();
                receiveThread = new Thread(new ThreadStart(startListening));
                sendThread = new Thread(new ThreadStart(startSend));

                start_flag = true;
                receiveThread.Start();

                sendThread.Start();
                btn_disconnect.IsEnabled = true;
                btn_connect.IsEnabled = false;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }

            
        }

        //假断开，实则上为不发送数据
        private void btn_disconnect_Click(object sender, RoutedEventArgs e)
        {
            start_flag = false;
            start_flag = false;
            receiveThread.Interrupt();
            sendThread.Interrupt();
            if (tcpClient.Connected)
            {
                tcpClient.Close();
            }
            btn_connect.IsEnabled = true;
            btn_disconnect.IsEnabled = false;
        }

        //退出时断开
        private void UserControl_Unloaded(object sender, RoutedEventArgs e)
        {

        }

        //添加数据包
        public void AddPackage(Package package)
        {
            packagesSend.Enqueue(package);
        }
    }
}
